package com.gome.boot.config.ibmmq;

import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.JmsTransactionManager;
import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
import org.springframework.jms.core.JmsOperations;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * IbmMQ基础配置.
 *
 * @author baoxiufeng
 */
public abstract class BaseIbmMqConfig {
    private static final String KEY_IBMMQ_HOST = "ibm.mq.host";
    private static final String KEY_IBMMQ_PORT = "ibm.mq.port";
    private static final String KEY_IBMMQ_QUEUE_MANAGER = "ibm.mq.queue_manager";
    private static final String KEY_IBMMQ_CHANNEL = "ibm.mq.channel";
    private static final String KEY_IBMMQ_CCSID = "ibm.mq.ccsid";
    private static final String KEY_IBMMQ_USERNAME = "ibm.mq.username";
    private static final String KEY_IBMMQ_PASSWORD = "ibm.mq.password";
    private static final String KEY_IBMMQ_RECEIVE_TIMEOUT = "ibm.mq.receive_timeout";

    @Autowired
    protected Environment env;

    /**
     * 生成指定类型的队列连接工厂实例.
     *
     * @param type 队列类型
     * @return 队列连接工厂实例
     */
    private MQQueueConnectionFactory getConnectionFactory(String type) {
        MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
        try {
            if (type == null) {
                mqQueueConnectionFactory.setHostName(env.getRequiredProperty(KEY_IBMMQ_HOST));
                mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
                mqQueueConnectionFactory.setCCSID(env.getProperty(KEY_IBMMQ_CCSID, Integer.class, 1208));
                mqQueueConnectionFactory.setChannel(env.getRequiredProperty(KEY_IBMMQ_CHANNEL));
                mqQueueConnectionFactory.setPort(env.getRequiredProperty(KEY_IBMMQ_PORT, Integer.class));
                mqQueueConnectionFactory.setQueueManager(env.getRequiredProperty(KEY_IBMMQ_QUEUE_MANAGER));
            } else {
                mqQueueConnectionFactory.setHostName(env.getRequiredProperty(type + "." + KEY_IBMMQ_HOST));
                mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
                mqQueueConnectionFactory.setCCSID(env.getProperty(type + "." + KEY_IBMMQ_CCSID, Integer.class, 1208));
                mqQueueConnectionFactory.setChannel(env.getRequiredProperty(type + "." + KEY_IBMMQ_CHANNEL));
                mqQueueConnectionFactory.setPort(env.getRequiredProperty(type + "." + KEY_IBMMQ_PORT, Integer.class));
                mqQueueConnectionFactory.setQueueManager(env.getRequiredProperty(type + "." + KEY_IBMMQ_QUEUE_MANAGER));
            }
        } catch (Exception e) {
            ;
        }
        return mqQueueConnectionFactory;
    }

    /**
     * 生成队列连接凭证实例.
     *
     * @param type 队列类型
     * @return 队列连接凭证实例
     */
    private UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(String type) {
        UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
        if (type == null) {
            userCredentialsConnectionFactoryAdapter.setUsername(env.getRequiredProperty(KEY_IBMMQ_USERNAME));
            userCredentialsConnectionFactoryAdapter.setPassword(env.getRequiredProperty(KEY_IBMMQ_PASSWORD));
        } else {
            userCredentialsConnectionFactoryAdapter.setUsername(env.getRequiredProperty(type + "." + KEY_IBMMQ_USERNAME));
            userCredentialsConnectionFactoryAdapter.setPassword(env.getRequiredProperty(type + "." + KEY_IBMMQ_PASSWORD));
        }
        userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(getConnectionFactory(type));
        return userCredentialsConnectionFactoryAdapter;
    }

    /**
     * 生成队列缓存连接工厂实例.
     *
     * @param type 队列类型
     * @return 队列缓存连接工厂实例
     */
    protected CachingConnectionFactory createCachingConnectionFactory(String type) {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter(type));
        cachingConnectionFactory.setSessionCacheSize(500);
        cachingConnectionFactory.setReconnectOnException(true);
        return cachingConnectionFactory;
    }

    /**
     * 构建队列事务管理器实例.
     * <br/>一般不需要.
     *
     * @param cachingConnectionFactory 队列缓存连接工厂实例
     * @return 队列事务管理器实例
     */
    protected PlatformTransactionManager createJmsTransactionManager(CachingConnectionFactory cachingConnectionFactory) {
        JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
        jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);
        return jmsTransactionManager;
    }

    /**
     * 构建JMS操作模板实例.
     * <br/>一般不需要.
     *
     * @param cachingConnectionFactory 队列缓存连接工厂实例
     * @return JMS操作模板实例
     */
    protected JmsOperations createJmsOperations(CachingConnectionFactory cachingConnectionFactory) {
        JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
        jmsTemplate.setReceiveTimeout(env.getRequiredProperty(KEY_IBMMQ_RECEIVE_TIMEOUT, Long.class));
        return jmsTemplate;
    }
}
